const Challenge = require('../models/Challenge');
const User = require('../models/User');
const { catchAsync } = require('../utils/errorHandler');

// 创建新挑战
exports.createChallenge = catchAsync(async (req, res) => {
  const {
    title,
    description,
    difficulty,
    category,
    concepts,
    instructions,
    startingTemplate,
    expectedOutput,
    testCases,
    timeLimit,
    points,
    badges,
    hints,
    relatedResources,
    isOfficial,
    isPublic,
    ageRange,
  } = req.body;

  // 创建挑战
  const challenge = await Challenge.create({
    title,
    description,
    difficulty,
    category,
    concepts,
    instructions,
    startingTemplate,
    expectedOutput,
    testCases,
    timeLimit,
    points,
    badges,
    hints,
    relatedResources,
    creator: req.user.id,
    isOfficial: req.user.role === 'admin' ? isOfficial : false, // 只有管理员可以创建官方挑战
    isPublic,
    ageRange,
  });

  res.status(201).json({
    success: true,
    message: '挑战创建成功',
    data: { challenge },
  });
});

// 获取挑战详情
exports.getChallenge = catchAsync(async (req, res) => {
  const challenge = await Challenge.findById(req.params.id)
    .populate('creator', 'username avatar')
    .populate('prerequisites', 'title difficulty')
    .populate('nextChallenges', 'title difficulty');

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 检查访问权限
  if (!challenge.isPublic && challenge.creator.toString() !== req.user.id && req.user.role !== 'admin') {
    return res.status(403).json({
      success: false,
      message: '您没有权限访问此挑战',
    });
  }

  // 更新统计数据
  challenge.stats.attempts += 1;
  await challenge.save({ validateBeforeSave: false });

  res.status(200).json({
    success: true,
    data: { challenge },
  });
});

// 更新挑战
exports.updateChallenge = catchAsync(async (req, res) => {
  // 查找挑战
  let challenge = await Challenge.findById(req.params.id);

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 检查权限
  if (challenge.creator.toString() !== req.user.id && req.user.role !== 'admin') {
    return res.status(403).json({
      success: false,
      message: '您没有权限更新此挑战',
    });
  }

  const {
    title,
    description,
    difficulty,
    category,
    concepts,
    instructions,
    startingTemplate,
    expectedOutput,
    testCases,
    timeLimit,
    points,
    badges,
    hints,
    relatedResources,
    isOfficial,
    isPublic,
    ageRange,
    prerequisites,
    nextChallenges,
  } = req.body;

  // 更新挑战
  challenge = await Challenge.findByIdAndUpdate(
    req.params.id,
    {
      title,
      description,
      difficulty,
      category,
      concepts,
      instructions,
      startingTemplate,
      expectedOutput,
      testCases,
      timeLimit,
      points,
      badges,
      hints,
      relatedResources,
      isOfficial: req.user.role === 'admin' ? isOfficial : challenge.isOfficial,
      isPublic,
      ageRange,
      prerequisites,
      nextChallenges,
    },
    {
      new: true,
      runValidators: true,
    }
  );

  res.status(200).json({
    success: true,
    message: '挑战更新成功',
    data: { challenge },
  });
});

// 删除挑战
exports.deleteChallenge = catchAsync(async (req, res) => {
  const challenge = await Challenge.findById(req.params.id);

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 检查权限
  if (challenge.creator.toString() !== req.user.id && req.user.role !== 'admin') {
    return res.status(403).json({
      success: false,
      message: '您没有权限删除此挑战',
    });
  }

  await challenge.remove();

  res.status(200).json({
    success: true,
    message: '挑战删除成功',
    data: null,
  });
});

// 获取挑战列表
exports.getChallenges = catchAsync(async (req, res) => {
  const page = parseInt(req.query.page, 10) || 1;
  const limit = parseInt(req.query.limit, 10) || 10;
  const skip = (page - 1) * limit;

  // 构建查询条件
  const query = {};
  
  // 非管理员只能看到公开的挑战或自己创建的挑战
  if (req.user.role !== 'admin') {
    query.$or = [{ isPublic: true }, { creator: req.user.id }];
  }
  
  // 过滤条件
  if (req.query.difficulty) query.difficulty = req.query.difficulty;
  if (req.query.category) query.category = req.query.category;
  if (req.query.isOfficial) query.isOfficial = req.query.isOfficial === 'true';
  if (req.query.concepts) query.concepts = { $in: req.query.concepts.split(',') };
  
  // 年龄范围过滤
  if (req.query.age) {
    const age = parseInt(req.query.age, 10);
    query['ageRange.min'] = { $lte: age };
    query['ageRange.max'] = { $gte: age };
  }

  // 排序条件
  let sort = {};
  if (req.query.sort) {
    switch (req.query.sort) {
      case 'popular':
        sort = { 'stats.attempts': -1 };
        break;
      case 'rating':
        sort = { 'stats.rating': -1 };
        break;
      case 'newest':
        sort = { createdAt: -1 };
        break;
      case 'difficulty_asc':
        sort = { difficulty: 1 };
        break;
      case 'difficulty_desc':
        sort = { difficulty: -1 };
        break;
      default:
        sort = { createdAt: -1 };
    }
  } else {
    sort = { createdAt: -1 };
  }

  // 执行查询
  const challenges = await Challenge.find(query)
    .sort(sort)
    .skip(skip)
    .limit(limit)
    .populate('creator', 'username avatar')
    .select('title description difficulty category concepts points stats createdAt');

  // 获取总数
  const total = await Challenge.countDocuments(query);

  res.status(200).json({
    success: true,
    data: {
      challenges,
      pagination: {
        total,
        page,
        limit,
        pages: Math.ceil(total / limit),
      },
    },
  });
});

// 提交挑战
exports.submitChallenge = catchAsync(async (req, res) => {
  const { solution, completionTime } = req.body;
  const challengeId = req.params.id;

  // 查找挑战
  const challenge = await Challenge.findById(challengeId);

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 验证解决方案（实际项目中需要更复杂的验证逻辑）
  const isCorrect = validateSolution(solution, challenge.testCases);

  // 更新统计数据
  challenge.stats.completions += isCorrect ? 1 : 0;
  
  // 更新平均完成时间
  if (isCorrect && completionTime) {
    const totalCompletionTime = challenge.stats.averageCompletionTime * challenge.stats.completions;
    challenge.stats.averageCompletionTime = (totalCompletionTime + completionTime) / (challenge.stats.completions + 1);
  }
  
  await challenge.save({ validateBeforeSave: false });

  // 如果解决方案正确，更新用户学习进度
  if (isCorrect) {
    const user = await User.findById(req.user.id);
    
    // 添加已完成的挑战
    if (!user.learningProgress.completedChallenges.includes(challengeId)) {
      user.learningProgress.completedChallenges.push(challengeId);
      
      // 增加经验值
      user.learningProgress.experience += challenge.points;
      
      // 检查是否需要升级
      const experienceNeeded = user.learningProgress.level * 100; // 简单的升级公式
      if (user.learningProgress.experience >= experienceNeeded) {
        user.learningProgress.level += 1;
        user.learningProgress.experience -= experienceNeeded;
      }
      
      // 检查是否获得徽章
      if (challenge.badges && challenge.badges.length > 0) {
        challenge.badges.forEach(badge => {
          user.learningProgress.badges.push({
            name: badge.name,
            description: badge.description,
            dateEarned: new Date(),
          });
        });
      }
      
      await user.save({ validateBeforeSave: false });
    }
  }

  res.status(200).json({
    success: true,
    data: {
      isCorrect,
      points: isCorrect ? challenge.points : 0,
      message: isCorrect ? '恭喜！你成功完成了挑战。' : '解决方案不正确，请再试一次。',
    },
  });
});

// 评价挑战
exports.rateChallenge = catchAsync(async (req, res) => {
  const { rating } = req.body;
  const challengeId = req.params.id;

  // 验证评分
  if (rating < 1 || rating > 5) {
    return res.status(400).json({
      success: false,
      message: '评分必须在1到5之间',
    });
  }

  // 查找挑战
  const challenge = await Challenge.findById(challengeId);

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 更新评分
  const totalRating = challenge.stats.rating * challenge.stats.ratingCount;
  challenge.stats.ratingCount += 1;
  challenge.stats.rating = (totalRating + rating) / challenge.stats.ratingCount;

  await challenge.save({ validateBeforeSave: false });

  res.status(200).json({
    success: true,
    message: '评分提交成功',
    data: {
      rating: challenge.stats.rating,
      ratingCount: challenge.stats.ratingCount,
    },
  });
});

// 获取推荐挑战
exports.getRecommendedChallenges = catchAsync(async (req, res) => {
  // 获取用户信息
  const user = await User.findById(req.user.id);

  // 获取用户已完成的挑战
  const completedChallenges = user.learningProgress.completedChallenges;

  // 构建查询条件
  const query = {
    _id: { $nin: completedChallenges }, // 排除已完成的挑战
    isPublic: true,
    'ageRange.min': { $lte: user.age || 10 },
    'ageRange.max': { $gte: user.age || 10 },
  };

  // 根据用户级别推荐适当难度的挑战
  if (user.learningProgress.level <= 3) {
    query.difficulty = '初级';
  } else if (user.learningProgress.level <= 7) {
    query.difficulty = '中级';
  } else {
    query.difficulty = '高级';
  }

  // 执行查询
  const challenges = await Challenge.find(query)
    .limit(5)
    .populate('creator', 'username avatar')
    .select('title description difficulty category concepts points');

  res.status(200).json({
    success: true,
    data: { challenges },
  });
});

// 获取学习路径
exports.getLearningPath = catchAsync(async (req, res) => {
  // 获取用户信息
  const user = await User.findById(req.user.id);

  // 获取用户已完成的挑战
  const completedChallenges = user.learningProgress.completedChallenges;

  // 构建查询条件
  const query = {
    isPublic: true,
    isOfficial: true, // 只包含官方挑战
    'ageRange.min': { $lte: user.age || 10 },
    'ageRange.max': { $gte: user.age || 10 },
  };

  // 执行查询
  const allChallenges = await Challenge.find(query)
    .populate('prerequisites')
    .populate('nextChallenges')
    .select('title difficulty category concepts prerequisites nextChallenges');

  // 构建学习路径
  const learningPath = buildLearningPath(allChallenges, completedChallenges);

  res.status(200).json({
    success: true,
    data: { learningPath },
  });
});

// 解锁提示
exports.unlockHint = catchAsync(async (req, res) => {
  const { hintIndex } = req.body;
  const challengeId = req.params.id;

  // 查找挑战
  const challenge = await Challenge.findById(challengeId);

  if (!challenge) {
    return res.status(404).json({
      success: false,
      message: '挑战不存在',
    });
  }

  // 检查提示是否存在
  if (!challenge.hints || !challenge.hints[hintIndex]) {
    return res.status(404).json({
      success: false,
      message: '提示不存在',
    });
  }

  // 获取提示
  const hint = challenge.hints[hintIndex];

  // 检查用户是否有足够的积分
  const user = await User.findById(req.user.id);
  if (user.learningProgress.experience < hint.unlockCost) {
    return res.status(400).json({
      success: false,
      message: '积分不足，无法解锁提示',
    });
  }

  // 扣除积分
  user.learningProgress.experience -= hint.unlockCost;
  await user.save({ validateBeforeSave: false });

  res.status(200).json({
    success: true,
    message: '提示解锁成功',
    data: {
      hint: hint.content,
      remainingExperience: user.learningProgress.experience,
    },
  });
});

// 模拟验证解决方案的函数（实际项目中需要更复杂的验证逻辑）
const validateSolution = (solution, testCases) => {
  // 这里是简单的模拟逻辑，实际项目中需要更复杂的验证
  // 例如，可能需要在沙箱环境中运行代码并比较输出结果
  return Math.random() > 0.3; // 70%的概率通过，仅用于演示
};

// 构建学习路径的函数
const buildLearningPath = (allChallenges, completedChallenges) => {
  // 将挑战分为已完成和未完成
  const completed = allChallenges.filter(challenge => 
    completedChallenges.includes(challenge._id.toString())
  );
  
  const notCompleted = allChallenges.filter(challenge => 
    !completedChallenges.includes(challenge._id.toString())
  );

  // 找出下一步应该完成的挑战（没有前置要求或前置要求已完成的挑战）
  const nextChallenges = notCompleted.filter(challenge => {
    // 如果没有前置要求，可以直接完成
    if (!challenge.prerequisites || challenge.prerequisites.length === 0) {
      return true;
    }
    
    // 检查所有前置要求是否已完成
    return challenge.prerequisites.every(prereq => 
      completedChallenges.includes(prereq._id.toString())
    );
  });

  // 按难度排序
  const sortedNextChallenges = nextChallenges.sort((a, b) => {
    const difficultyOrder = { '初级': 1, '中级': 2, '高级': 3 };
    return difficultyOrder[a.difficulty] - difficultyOrder[b.difficulty];
  });

  return {
    completed,
    nextChallenges: sortedNextChallenges,
    future: notCompleted.filter(challenge => !nextChallenges.includes(challenge)),
  };
};